﻿//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: IStorage.cs
//
//  Description: This interface represents a storage class.
// 
//--------------------------------------------------------------------------

using System;
using Chili.Opf3;
using Chili.Opf3.Query;

namespace Chili.Opf3.Storages
{
	/// <summary>This interface is implemented by a class to represent a physical storage.</summary>
	/// <remarks>
	/// 	<para>A class that encapsulates a physical storage (for example:
	///     <see cref="Opf3.Storages.OleDb.AccessStorage">AccessStorage</see>) has to implement
	///     this interface to make sure that the framework recognizes it as storage and can use
	///     it. It contains the main functionality to execute a command on the storage, to get
	///     an <see cref="Opf3.ObjectReader{T}">ObjectReader</see> and also a method
	///     <see cref="Opf3.Storages.IStorage.ResolveStorageNullValue">ResolveStorageNullValue</see>
	///     that is invoked by the
	///     <see cref="Opf3.Storages.ObjectDataAdapter">ObjectDataAdapter</see> to resolve
	///     DBNulls that are returned by the storage.</para>
	/// 	<para><b>Attention:</b> Please implement at least a constructor that takes as
	///     argument the connection string.</para>
	/// </remarks>
	/// <example>
	/// <see cref="Opf3.Storages.MsSql.MsSqlStorage">MsSqlStorage</see>, 
	/// <see cref="Opf3.Storages.Oracle.OracleStorage">OracleStorage</see> or any other storage that comes with the
	/// framework.
	/// </example>
	public interface IStorage
	{
		/// <summary>
		/// Executes a command on the storage that does not expect any results. It the method
		/// returns an argument it is used by the framework to set the
		/// <see cref="Opf3.FieldAttribute.AutoNumber">AutoNumber</see> property of the persistent
		/// object.
		/// </summary>
		/// <param name="query"><see cref="Opf3.Query.IQuery">IQuery</see> that is compiled and executed on the storage.</param>
		object ExecuteCommand(IQuery query);

		/// <summary>
		/// Executes and compiles the <see cref="Opf3.Query.IQuery">IQuery</see> and returns
		/// an <see cref="Opf3.ObjectReader{T}">ObjectReader</see> with the resultsset.
		/// </summary>
		/// <param name="context">
		/// 	<see cref="Opf3.ObjectContext">ObjectContext</see> that is connected with the
		/// <see cref="Opf3.ObjectReader{T}">ObjectReader</see>.
		/// </param>
		/// <param name="query">
		/// 	<see cref="Opf3.Query.IQuery">IQuery</see> that is compiled and executed on the
		/// storage.
		/// </param>
		ObjectReader<T> ExecuteReader<T>(ObjectContext context, IQuery query);

		/// <summary>
		/// Handles the DBNull value for the given type.
		/// </summary>
		/// <param name="value">Value that should be handled.</param>
		/// <param name="type">Type of the value that is handled.</param>
		object ResolveStorageNullValue(object value, Type type);

		/// <summary>
		/// Returns the list of registered classes that implement the 
		/// <see cref="IStorageCommandBuilder">IStorageCommandBuilder</see> interfaces. Those classes
		/// provide the fuctionality to convert storage independent queries to storage dependent queries.
		/// </summary>
		StorageCommandBuilderCollection StorageCommandBuilders
		{
			get;
		}
	}
}
